""" 

    Network.py used in RepresentedBy Facebook application
    http://apps.facebook.com/representedby/
        
    This page goes through all of your friends data and calculates some fun facts about how big your
    network of influence really is within the government.
     
"""

__author__ = "Will Turnage (will@wubbahed.com)"
__version__ = "0.1.0"
__copyright__ = "Copyright (c) 2009 wubbahed.com"
__license__ = "GPLv3"


import os
import wsgiref.handlers
import facebook
import const
import string

from sets import Set
from django.utils import simplejson
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from google.appengine.ext import db
from utils import fbUtil, dbUtil, UserDistrict, SunlightUtil

class MainHandler(webapp.RequestHandler):
    def post(self):
        
        try:
            
            #check if Facebook app is installed
            self.facebookapi = fbUtil().checkFacebookAppInstalled(self, True, "network")
            if self.facebookapi is None:
                return

            myvars = {"section": "goodies"}
            percent_data = {}
            
            profiletab = self.request.get('tab', default_value=None)
            if profiletab is None:
                percent_data["newsfeed"] = True
                path = os.path.join(os.path.dirname(__file__), '../templates/heading.fbml')
                self.response.out.write(template.render(path, myvars))
            else:
                percent_data["newsfeed"] = False
                
            friend_ids = self.facebookapi.friends.get()
            if friend_ids is None:
                friend_ids = [self.facebookapi.uid]
            elif len(friend_ids) == 0:
                friend_ids = [self.facebookapi.uid]
            else:
                friend_ids.append(self.facebookapi.uid)
                
            friends_with_app_ids = self.facebookapi.friends.getAppUsers()
            if friends_with_app_ids is None:
                friends_with_app_ids = [self.facebookapi.uid]
            elif len(friends_with_app_ids) == 0:
                friends_with_app_ids = [self.facebookapi.uid]
            else:
                friends_with_app_ids.append(self.facebookapi.uid)
  
            friend_count = len(friends_with_app_ids)
            non_US_friends = 0
            unknown_friends = 0
            
            rep_set = {}
            states = {}
            sen_set = Set([])
            
            parties = {"D":[], "R":[]}
            features = { "twitter_id": [], "official_rss": [], "email": [], "youtube_url": [] }
            popularity = {"state":{"states":[], "count":0}}
            
            results = []
            if friends_with_app_ids is not None:
                if len(friends_with_app_ids) > 0:
                    for friend in friends_with_app_ids:
                        query = UserDistrict.all()
                        query.filter("uid =", int(friend))
                        results = query.fetch(1)
      
                        for result in results:
                            try:
                                friend_ids.remove(str(result.uid))
                            except ValueError:
                                pass
                            
                            if result.rep:
                                if rep_set.has_key(result.rep):
                                    # rep_set[result.rep].append(appUser)
                                    rep_set[result.rep]["friends"] = rep_set[result.rep]["friends"]+ 1
                                else:
                                    # rep_set[result.rep] = [[{"id": result.rep, "name": const.FRIENDLY_NAME[result.rep]}], appUser]
                                    rep_set[result.rep] = {"id": result.rep, "name": const.FRIENDLY_NAME[result.rep], "friends": 1}
                                    
                                    for party in parties.keys():
                                        if result.rep in const.PARTY_AFFILIATIONS[party]:
                                            parties[party].append(result.rep)
            
                                    for feature in features.keys():
                                        if result.rep in const.LEGISLATOR_ATTR[feature]:
                                            features[feature].append(result.rep)                                   
                                    
                            if result.state:
                                if states.has_key(result.state):
                                    # states[result.state].append(appUser)
                                    states[result.state]["friends"] = states[result.state]["friends"]+ 1
                                    if (states[result.state]["friends"] == popularity["state"]["count"]):
                                        popularity["state"]["states"].append(str.title(const.STATES[result.state]))
                                    elif (states[result.state]["friends"] > popularity["state"]["count"]):
                                        popularity["state"]["states"] = [str.title(const.STATES[result.state])]  
                                else:
                                    #states[result.state] = [[], appUser]
                                    states[result.state] = {"state": result.state, "friends": 1, "senators":[]}
                                    for senator in const.LEGISLATORS_BY_STATE[result.state]["senators"]:
                                        sen_set.add(senator)
                                    #    states[result.state][0].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                        states[result.state]["senators"].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                        
                                        for party in parties.keys():
                                            if senator in const.PARTY_AFFILIATIONS[party]:
                                                parties[party].append(senator)
                
                                        for feature in features.keys():
                                            if senator in const.LEGISLATOR_ATTR[feature]:
                                                features[feature].append(senator)
                                            
                                              
            friends_loc = self.facebookapi.users.getInfo(friend_ids, ['uid', 'current_location'])  
            #for all your other friends, try and look up their information
            for friend in friends_loc :
                if friend:
                    sunlight = SunlightUtil(const.SUNLIGHT_API_KEY)
                    friendInfo = sunlight.getDistrictForUser(friend["uid"], friend["current_location"])
            
                    if friendInfo is not None:
                        if (friendInfo.has_key("state")):
                            
                            friend_count = friend_count + 1
                            if states.has_key(friendInfo["state"]):
                                states[friendInfo["state"]]["friends"] = states[friendInfo["state"]]["friends"]+ 1
                                if (states[friendInfo["state"]]["friends"] == popularity["state"]["count"]):
                                    popularity["state"]["states"].append(str.title(const.STATES[friendInfo["state"]]))
                                elif (states[friendInfo["state"]]["friends"] > popularity["state"]["count"]):
                                    popularity["state"]["states"] = [str.title(const.STATES[friendInfo["state"]])] 
                            else:                
                                #states[friendInfo["state"]] = [[], friend["uid"]]
                                states[friendInfo["state"]] = {"state": friendInfo["state"], "friends": 1, "senators":[]}
                                for senator in const.LEGISLATORS_BY_STATE[friendInfo["state"]]["senators"]:
                                    sen_set.add(senator)
                                    #states[friendInfo["state"]][0].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                    states[friendInfo["state"]]["senators"].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                    for party in parties.keys():
                                        if senator in const.PARTY_AFFILIATIONS[party]:
                                            parties[party].append(senator)
            
                                    for feature in features.keys():
                                        if senator in const.LEGISLATOR_ATTR[feature]:
                                            features[feature].append(senator)

                            row = sunlight.getLegislatorsFromLocationRow(friendInfo)
                            if row.has_key("rep"):
                                if rep_set.has_key(row["rep"]):
                                    rep_set[row["rep"]]["friends"] = rep_set[row["rep"]]["friends"] + 1
                                else:
                                    rep_set[row["rep"]] = {"id": row["rep"], "name": const.FRIENDLY_NAME[row["rep"]], "friends": 1}
                                    for party in parties.keys():
                                        if senator in const.PARTY_AFFILIATIONS[party]:
                                            parties[party].append(senator)
            
                                    for feature in features.keys():
                                        if senator in const.LEGISLATOR_ATTR[feature]:
                                            features[feature].append(senator)
                    else:
                        if friend["current_location"] is not None:
                            if friend["current_location"].has_key("country") :
                                if friend["current_location"]["country"] != "United States" :
                                    non_US_friends = non_US_friends + 1
                                else:
                                    unknown_friends = unknown_friends + 1
                            else:
                                unknown_friends = unknown_friends + 1
                        else:
                            unknown_friends = unknown_friends + 1
                else:
                    unknown_friends = unknown_friends + 1
                        
                                                             

            committee_set = Set(const.COMMITTEES.keys())
            committee_member_set = Set([])
            committee_chair_set = Set([])
            for member in rep_set.keys():
                if const.COMMITTEE_BY_MEMBER.has_key(member):
                    for comm in const.COMMITTEE_BY_MEMBER[member]:
                        committee_member_set.add(comm)
                if const.COMMITTEE_BY_CHAIR.has_key(member):
                    for comm in const.COMMITTEE_BY_CHAIR[member]:
                        committee_chair_set.add(comm)
            for member in sen_set:
                if const.COMMITTEE_BY_MEMBER.has_key(member):
                    for comm in const.COMMITTEE_BY_MEMBER[member]:
                        committee_member_set.add(comm)
                if const.COMMITTEE_BY_CHAIR.has_key(member):
                    for comm in const.COMMITTEE_BY_CHAIR[member]:
                        committee_chair_set.add(comm)
            
            
            
            total_network_legislators = (len(rep_set) + len(sen_set))
            total_legislators =  (len(const.REPRESENTATIVES) + len(const.SENATORS)) 
                      
            if total_network_legislators > 0:
                percent_data["democrats_you"] = (100 * len(parties["D"])) / total_network_legislators
                percent_data["republicans_you"] = (100 * len(parties["R"])) / total_network_legislators
                percent_data["total_network_legislators"] = total_network_legislators
                percent_data["twitter_you"] = (100 * len(features["twitter_id"])) / total_network_legislators
                percent_data["youtube_you"] = (100 * len(features["youtube_url"])) / total_network_legislators
            else:
                percent_data["democrats_you"] = 0
                percent_data["republicans_you"] = 0
                percent_data["total_network_legislators"] = 0        
                percent_data["twitter_you"] = 0
                percent_data["youtube_you"] = 0
            
            percent_data["democrats_all"] = (100 * len(const.PARTY_AFFILIATIONS["D"])) / total_legislators
            percent_data["republicans_all"] = (100 * len(const.PARTY_AFFILIATIONS["R"])) / total_legislators
            for feature in features.keys():
                percent_data[feature] = len(features[feature])
            percent_data["twitter_all"] = (100 * len(const.LEGISLATOR_ATTR["twitter_id"])) / total_legislators
            percent_data["youtube_all"] = (100 * len(const.LEGISLATOR_ATTR["youtube_url"])) / total_legislators
            percent_data["influence_percent"] = (100 * total_network_legislators) / total_legislators
            percent_data["total_friends"] = friend_count + non_US_friends + unknown_friends
            percent_data["known_friends"] = friend_count
            percent_data["non_US_friends"] = non_US_friends
            percent_data["unknown_friends"] = unknown_friends
            percent_data["friend_reps"] = rep_set.values()
            percent_data["friend_sen"] = states.values()
            percent_data["house_total"] = len(const.REPRESENTATIVES)
            percent_data["sen_total"] = len(const.SENATORS)
            percent_data["committee_total"] = len(const.COMMITTEES)
            percent_data["house_count"] = len(rep_set)
            percent_data["sen_count"] = len(sen_set)
            percent_data["total_count"] = total_legislators
            percent_data["committee_member_count"] = len(committee_member_set)
            percent_data["committee_chair_count"] = len(committee_chair_set)
            percent_data["popular_state"] = popularity["state"]["states"]
            statenames = ""
            statecolors = ""
            for i in states.keys():
                statenames = statenames + i
                statecolors = statecolors + "0,"
            
            percent_data["state_names"] = statenames
            percent_data["state_colors"] = string.rstrip(statecolors,',')
            
            path = os.path.join(os.path.dirname(__file__), '../templates/network.fbml')
            self.response.out.write(template.render(path, percent_data ))
            
            
        except urlfetch.DownloadError, e:
            path = os.path.join(os.path.dirname(__file__), '../templates/error.fbml')
            self.response.out.write(template.render(path, {"error":"Sorry, Google AppEngine ain't working" }))
            
        except facebook.FacebookError, e:
            path = os.path.join(os.path.dirname(__file__), '../templates/error.fbml')
            self.response.out.write(template.render(path, {"error":"Sorry, Facebook ain't working - " + str(e.msg)})) 
            
  
def main():
	application = webapp.WSGIApplication([('/fb/network', MainHandler)],
									   debug=True)
	run_wsgi_app(application)

# load our custom filters		   
webapp.template.register_template_library('customfilters')

if __name__ == '__main__':
	main()
